package com.hkts.naturalgas.datahandler.sheldertask;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hkts.naturalgas.association.entity.ProvideDataAddress;
import com.hkts.naturalgas.association.service.IHktsRequestAddressAssociationService;
import com.hkts.naturalgas.association.service.IProvideDataAddressService;
import com.hkts.naturalgas.curvesettings.entity.CurveSettings;
import com.hkts.naturalgas.curvesettings.service.ICurveSettingsService;
import com.hkts.naturalgas.datahandler.constance.EnviromentConstance;
import com.hkts.naturalgas.dictionaries.entity.HktsEnvironmentProtectionDictionaries;
import com.hkts.naturalgas.dictionaries.entity.HktsEnvironmentProtectionItem;
import com.hkts.naturalgas.dictionaries.service.IHktsEnvironmentProtectionDictionariesService;
import com.hkts.naturalgas.dictionaries.service.IHktsEnvironmentProtectionItemService;
import com.hkts.naturalgas.dictionaries.utils.DBUtils;
import com.hkts.naturalgas.utils.SnowFlakeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @ClassNameDataSynchronization
 * @Description
 * @Author yck
 * @Date2021-12-20 8:55
 * @Version V1.0
 **/
@Configuration      //1.主要用于标记配置类，兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
@Lazy(false)
@Slf4j
public class DataSynchronization {
    @Autowired
    public DBUtils dBUtils;
    @Autowired
    public IHktsEnvironmentProtectionDictionariesService iHktsEnvironmentProtectionDictionariesService;

    @Autowired
    public IHktsRequestAddressAssociationService iHktsRequestAddressAssociationService;
    @Autowired
    public IProvideDataAddressService iProvideDataAddressService;
    @Autowired
    public IHktsEnvironmentProtectionItemService iHktsEnvironmentProtectionItemService;
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;
    Map<String, List<HktsEnvironmentProtectionItem>> itemMap = new HashMap<String, List<HktsEnvironmentProtectionItem>>();
    @Autowired
    public ICurveSettingsService iCurveSettingsService;
    //曲线设置 用于计算当前曲线的运行时间和剩余时间
    Map<String, List<CurveSettings>> curveSettingMap = new HashMap<String, List<CurveSettings>>();

   // @Scheduled(cron = "*/20 * * * * ?")
    public void dataSynchronization() {
        CompletableFuture<Void> voidCompletableFuture1 = CompletableFuture.runAsync(() -> {
            log.info("数据库同步");
            QueryWrapper<ProvideDataAddress> query = Wrappers.query();
            // ProvideDataAddress one = iProvideDataAddressService.getOne(query);
            List<ProvideDataAddress> list = iProvideDataAddressService.list(query);
            for (int g = 0; g < list.size(); g++) {
                HktsEnvironmentProtectionDictionaries hktsEnvironmentProtectionDictionaries = new HktsEnvironmentProtectionDictionaries();
                hktsEnvironmentProtectionDictionaries.setIsEnable(EnviromentConstance.IS_ENABLE);
                List<HktsEnvironmentProtectionDictionaries> hktsEnvironmentProtectionDictionaries1 = iHktsEnvironmentProtectionDictionariesService.selectList(hktsEnvironmentProtectionDictionaries);
                itemMap = iHktsEnvironmentProtectionItemService.getItemMap(hktsEnvironmentProtectionDictionaries1);
                String id = String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId());
                List<String> sqlList = new ArrayList<>();
                List<String> deleteSqlList = new ArrayList<>();
                //封装曲线设置用到的字段
                curveSettingMap = iCurveSettingsService.selectMapforShelder(hktsEnvironmentProtectionDictionaries1);
                Map<String, Float> timeMap = new HashMap<String, Float>();
                for (int i = 0; i < hktsEnvironmentProtectionDictionaries1.size(); i++) {
                    try {
                        deleteSqlList.add("delete from " + hktsEnvironmentProtectionDictionaries1.get(i).getTableName());
                        Map<String, Object> lastRow = dBUtils.getLastRow(hktsEnvironmentProtectionDictionaries1.get(i).getTableName());
                        List<HktsEnvironmentProtectionItem> hktsEnvironmentProtectionItems = itemMap.get(hktsEnvironmentProtectionDictionaries1.get(i).getId());
                        Iterator<HktsEnvironmentProtectionItem> iterator = hktsEnvironmentProtectionItems.iterator();
                        for (Iterator iter = iterator; iter.hasNext(); ) {
                            HktsEnvironmentProtectionItem item = (HktsEnvironmentProtectionItem) iter.next();
                            if (!item.getFieldName().equals("time") && !item.getIsAtmosphere().equals("1")) {
                                iter.remove();
                            }
                        }
                        if (hktsEnvironmentProtectionItems.size() < 2) {
                            continue;
                        }
                        String updateSql = dBUtils.updateSql(hktsEnvironmentProtectionDictionaries1.get(i).getTableName(),
                                hktsEnvironmentProtectionItems,
                                lastRow, id);
                        sqlList.add(updateSql);

                        if (StringUtils.isNotBlank(hktsEnvironmentProtectionDictionaries1.get(i).getCurveId())) {
                            List<CurveSettings> curveSettings = curveSettingMap.get(hktsEnvironmentProtectionDictionaries1.get(i).getCurveId());
                            int totalSeconds = 0;
                            int runSeconds = 0;
                            for (int j = 0; j < curveSettings.size() - 2; j++) {
                                if (curveSettings.get(j).getCurrentNode().equals(EnviromentConstance.IS_CURRENT_NODE)) {
                                    runSeconds = totalSeconds + curveSettings.get(j).getCurrentSeconds();
                                }
                                totalSeconds = totalSeconds + curveSettings.get(j).getTotalSeconds();
                            }
                            //运行时间
                            timeMap.put(hktsEnvironmentProtectionDictionaries1.get(i).getTableName() + "_running_time", (float) runSeconds / 3600);
                            //
                            if (runSeconds < totalSeconds) {
                                timeMap.put(hktsEnvironmentProtectionDictionaries1.get(i).getTableName() + "_remaining_time", (float) (totalSeconds - runSeconds) / 3600);
                            } else {
                                timeMap.put(hktsEnvironmentProtectionDictionaries1.get(i).getTableName() + "_remaining_time", 0f);
                            }
                        }

                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }

                //处理燃烧架时间字段
                if (timeMap.size() > 0) {
                    deleteSqlList.add("delete from roasting_time");
                    StringBuffer insertBuffer = new StringBuffer();
                    SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    StringBuffer valuesBuffer = new StringBuffer();
                    insertBuffer.append("insert into roasting_time ( id,time,");
                    valuesBuffer.append("values ('").append(id).append("','")
                            .append(sim.format(new Date())).append("',");

                    DecimalFormat decimalFormat = new DecimalFormat(".00");
                    Iterator<Map.Entry<String, Float>> iterator = timeMap.entrySet().iterator();//返回所有的entry实体
                    while (iterator.hasNext()) {
                        Map.Entry<String, Float> next1 = iterator.next();
                        String key = next1.getKey();
                        Float value = next1.getValue();
                        insertBuffer.append(key).append(",");
                        try {
                            valuesBuffer.append(decimalFormat.parse(decimalFormat.format(value))).append(",");
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                    }
                    insertBuffer.deleteCharAt(insertBuffer.length() - 1).append(")");
                    valuesBuffer.deleteCharAt(valuesBuffer.length() - 1).append(")");
                    insertBuffer.append(" ").append(valuesBuffer);
                    //  log.info("燃烧架时间插入数据库sql{}:"+insertBuffer);
                    sqlList.add(insertBuffer.toString());
                }
                //批量执行sql
                executeUpdate(deleteSqlList, sqlList, list.get(g));
            }
        }, threadPoolExecutor);
    }

    public void executeUpdate(List<String> deleteSql, List<String> sqlList, ProvideDataAddress one) {
        String URL = "jdbc:mysql://" + one.getUrl() + "?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT";
        String USER = one.getUsername();
        String PASSWORD = one.getPassword();
        Connection conn = null;
        Statement pst = null;
        Map<String, Object> resultMap = new HashMap<>();
        //1.加载驱动程序
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            //设置超时时间
            DriverManager.setLoginTimeout(1);
            //2.获得数据库链接
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
            pst = conn.createStatement();
            //3.通过数据库的连接操作数据库，实现增删改查（使用Statement类）
            for (int i = 0; i < deleteSql.size(); i++) {
                pst.addBatch(deleteSql.get(i));
            }
            for (int i = 0; i < sqlList.size(); i++) {
                pst.addBatch(sqlList.get(i));
            }
            int[] ints = pst.executeBatch();
            log.info("批量插入条数：{}", ints.length);

        } catch (Exception e) {
            System.out.println(e.getMessage());
            log.error(e.getMessage());

            //e.printStackTrace();
        } finally {
            try {
                if (pst != null) {
                    pst.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
